package com.dave.gd.core.context;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import org.springframework.core.NamedThreadLocal;

import com.dave.gd.common.log.ILogger;
import com.dave.gd.common.log.LoggerFactory;
import com.dave.gd.core.rule.ERuleMode;
import com.dave.gd.core.rule.RuleResult;

/**
 * Created by linzq on 2014/11/17.
 */
public class SessionContext {
    
    private static final ILogger                          LOG               = LoggerFactory
                                                                                .getLogger(SessionContext.class);
    /**
     * 基本信息本地线程存储变量。
     */
    private static final ThreadLocal<Map<String, Object>> BASE_INFO         = new NamedThreadLocal<Map<String, Object>>(
                                                                                "基本信息");
    
    private static final String                           RULE_MODE         = "RULE_MODE";
    
    private static final String                           WARN_RULE_RESULTS = "WARN_RULE_RESULTS";
    
    private static final String                           ALL_RULE_RESULTS  = "ALL_RULE_RESULTS";
    
    private static final String                           ENTT_BACKUP_CACHE = "ENTT_BACKUP_CACHE";
    
    // 本地线程池操作-begin
    
    /**
     * 设置本地线程变量。
     *
     * @param name
     *            名称
     * @param value
     *            值
     */
    public static void putTheadLocalVariable(String name, Object value) {
        SessionContext.loadBaseInfo().put(name, value);
    }
    
    /**
     * 从本地线程中获取变量的值。
     *
     * @param name
     *            变量名称
     * @return 变量值
     */
    public static Object getTheadLocalVariable(String name) {
        return SessionContext.loadBaseInfo().get(name);
    }
    
    /**
     * 获取本地线程变量。
     *
     * @return 本地线程变量值
     */
    public static Map<String, Object> loadBaseInfo() {
        Map<String, Object> info = SessionContext.BASE_INFO.get();
        if (info == null) {
            info = new HashMap<String, Object>();
            SessionContext.BASE_INFO.set(info);
        }
        return info;
    }
    
    /**
     * 初始化本地线程变量。
     *
     * @return 本地线程变量的初始值
     */
    public static Map<String, Object> initialBaseInfo() {
        LOG.debug("初始化线程变量开始。。。。");
        Map<String, Object> info = SessionContext.BASE_INFO.get();
        if (info == null) {
            info = new HashMap<String, Object>();
            SessionContext.BASE_INFO.set(info);
        } else {
            info.clear();
        }
        LOG.debug("初始化线程变量结束。。。。");
        return info;
    }
    
    /**
     * 销毁本地线程变量。
     *
     */
    public static void clearBaseInfo() {
        Map<String, Object> info = SessionContext.BASE_INFO.get();
        if (info != null) {
            info.clear();
        }
    }
    
    // 本地线程池操作-end
    
    /**
     * 获取当前规则处理模式
     *
     * @return
     * @author wangzy
     *         2011-3-24 wangzy
     */
    public static ERuleMode getRuleMode() {
        ERuleMode rm;
        
        rm = (ERuleMode) getObject4TreadLocal(RULE_MODE);
        return rm == ERuleMode.DISABLE ? ERuleMode.DISABLE
            : ERuleMode.ENABLE;
    }
    
    /**
     * 修改规则处理模式
     *
     * @param rm
     */
    public static void setRuleMode(ERuleMode rm) {
        setObject2TreadLocal(RULE_MODE, rm);
    }
    
    /**
     * 从本地线程变量获取属性
     *
     * @param key
     * @return
     */
    public static Object getObject4TreadLocal(String key) {
        Map<String, Object> mapBaseInfo = BASE_INFO.get();
        if (mapBaseInfo != null) {
            return mapBaseInfo.get(key);
        }
        
        return null;
    }
    
    /**
     * 设置变量到本地现场
     *
     * @param key
     * @param value
     */
    public static void setObject2TreadLocal(String key, Object value) {
        SessionContext.putTheadLocalVariable(key, value);
    }
    
    public static void collectWarnResults(List<RuleResult> warnResults) {
        List<RuleResult> results = (List<RuleResult>) getObject4TreadLocal(WARN_RULE_RESULTS);
        if (results == null) {
            results = new ArrayList<RuleResult>();
        }
        results.addAll(warnResults);
        setObject2TreadLocal(WARN_RULE_RESULTS, results);
    }
    
    public static List<RuleResult> getWarnReults() {
        List<RuleResult> results = (List<RuleResult>) getObject4TreadLocal(WARN_RULE_RESULTS);
        if (results == null) {
            results = new ArrayList<RuleResult>();
        }
        return results;
    }
    
    public static void collectAllResults(List<RuleResult> allResults) {
        List<RuleResult> results = (List<RuleResult>) getObject4TreadLocal(ALL_RULE_RESULTS);
        if (results == null) {
            results = new ArrayList<RuleResult>();
        }
        results.addAll(allResults);
        setObject2TreadLocal(ALL_RULE_RESULTS, results);
    }
    
    public static List<RuleResult> getAllReults() {
        List<RuleResult> results = (List<RuleResult>) getObject4TreadLocal(ALL_RULE_RESULTS);
        if (results == null) {
            results = new ArrayList<RuleResult>();
        }
        return results;
    }
    
    public static ConcurrentMap<String, Object> getEnttBackupCache() {
        ConcurrentMap<String, Object> sessCache = (ConcurrentMap<String, Object>) getObject4TreadLocal(ENTT_BACKUP_CACHE);
        if (sessCache == null) {
            sessCache = new ConcurrentHashMap<String, Object>();
            setObject2TreadLocal(ENTT_BACKUP_CACHE, sessCache);
        }
        return (ConcurrentMap<String, Object>) getObject4TreadLocal(ENTT_BACKUP_CACHE);
    }
}
